#ifndef ELEMENTS_H_INCLUDED
#define ELEMENTS_H_INCLUDED

#include "constants.h"
#include "assert.h"
#include <iostream>

class Elements
{
public:
    Elements()
    {
        size_t i = 0, cur = 0;
        do {
            elems_[i] = cur;
            indexedElems_[i] = std::make_pair(cur, i);
            size_t j = 0;
            while (cur & (1 << (n + j))) {
                cur ^= (1 << (n + j));
                ++j;
            }
            cur ^= ((cur & (1 << j)) << n);
            cur ^= (1 << j);
            ++i;
        } while (i < NUM_VERTICES);
        sort(indexedElems_, indexedElems_ + NUM_VERTICES);
    }

    size_t operator[] (size_t idx) const
    {
        assert(0 <= idx && idx < NUM_VERTICES);
        return elems_[idx];
    }

    size_t findVertexIndex(size_t v) const
    {
        size_t res = std::lower_bound(indexedElems_, indexedElems_ + NUM_VERTICES,
            std::make_pair(v, (size_t)0))->second;
        assert(res < NUM_VERTICES && elems_[res] == v);
        return res;
    }

private:
    size_t elems_[NUM_VERTICES];
    std::pair<size_t, size_t> indexedElems_[NUM_VERTICES];
};

const Elements elements;

#endif//ELEMENTS_H_INCLUDED

